/**
 * @file test_wrapper_init.cpp
 * @author 心流 (iFlow CLI)
 * @brief 测试CLWrapper类的初始化和清理方法
 * @version 0.1
 * @date 2025-11-26
 *
 * @copyright Copyright (c) 2025
 *
 */
#define BOOST_TEST_MODULE TestWrapperInit
#include <CL/cl.h>

#include <boost/format.hpp>
#include <boost/test/included/unit_test.hpp>
#include <boost/timer/timer.hpp>

#include "wrapper.hpp"

// 测试CLWrapper的初始化和清理功能
BOOST_AUTO_TEST_CASE(TestCLWrapperInitAndDeInit)
{
    CLWrapper cl;

    // 测试初始化
    bool init_result = cl.Init();
    BOOST_CHECK(init_result == true);

    // 验证各个组件是否正确初始化
    BOOST_CHECK(cl.GetPlatformID() != nullptr);
    BOOST_CHECK(cl.GetDeviceID() != nullptr);
    BOOST_CHECK(cl.GetContext() != nullptr);
    BOOST_CHECK(cl.GetQueue() != nullptr);

    // 测试资源是否有效
    cl_uint max_compute_units = 0;
    cl_int  err               = clGetDeviceInfo(cl.GetDeviceID(),
                                 CL_DEVICE_MAX_COMPUTE_UNITS,
                                 sizeof(cl_uint),
                                 &max_compute_units,
                                 nullptr);
    BOOST_CHECK_EQUAL(err, CL_SUCCESS);
    BOOST_CHECK_GT(max_compute_units, 0);  // 应该至少有一个计算单元

    // 测试清理
    cl.DeInit();

    // 验证清理后资源是否被置空
    // 注意：这里我们只检查内部成员是否被置空，外部指针可能仍存在（但已无效）
    // 为了验证DeInit是否工作，我们重新初始化
    CLWrapper cl2;
    bool      init_result2 = cl2.Init();
    BOOST_CHECK(init_result2 == true);
    BOOST_CHECK(cl2.GetPlatformID() != nullptr);
    BOOST_CHECK(cl2.GetDeviceID() != nullptr);
    BOOST_CHECK(cl2.GetContext() != nullptr);
    BOOST_CHECK(cl2.GetQueue() != nullptr);

    cl2.DeInit();
}

// 测试CLWrapper的默认构造函数
BOOST_AUTO_TEST_CASE(TestCLWrapperDefaultConstructor)
{
    CLWrapper cl;

    // 初始状态下所有指针应为nullptr
    BOOST_CHECK(cl.GetPlatformID() == nullptr);
    BOOST_CHECK(cl.GetDeviceID() == nullptr);
    BOOST_CHECK(cl.GetContext() == nullptr);
    BOOST_CHECK(cl.GetQueue() == nullptr);

    // 初始化后应不为nullptr
    bool init_result = cl.Init();
    BOOST_CHECK(init_result == true);

    BOOST_CHECK(cl.GetPlatformID() != nullptr);
    BOOST_CHECK(cl.GetDeviceID() != nullptr);
    BOOST_CHECK(cl.GetContext() != nullptr);
    BOOST_CHECK(cl.GetQueue() != nullptr);

    cl.DeInit();
}

// 测试在清理后再初始化
BOOST_AUTO_TEST_CASE(TestCLWrapperReInit)
{
    CLWrapper cl;

    // 第一次初始化和清理
    bool init_result1 = cl.Init();
    BOOST_CHECK(init_result1 == true);

    BOOST_CHECK(cl.GetPlatformID() != nullptr);
    BOOST_CHECK(cl.GetDeviceID() != nullptr);
    BOOST_CHECK(cl.GetContext() != nullptr);
    BOOST_CHECK(cl.GetQueue() != nullptr);

    cl.DeInit();

    // 验证清理后再次初始化是否正常
    bool init_result2 = cl.Init();
    BOOST_CHECK(init_result2 == true);

    BOOST_CHECK(cl.GetPlatformID() != nullptr);
    BOOST_CHECK(cl.GetDeviceID() != nullptr);
    BOOST_CHECK(cl.GetContext() != nullptr);
    BOOST_CHECK(cl.GetQueue() != nullptr);

    cl.DeInit();
}

// 测试错误处理 - 虽然Init方法应该成功，但我们可以测试一些边界条件
BOOST_AUTO_TEST_CASE(TestCLWrapperErrorHandling)
{
    CLWrapper cl;

    bool init_result = cl.Init();
    BOOST_CHECK(init_result == true);

    // 验证获取的资源是否可以正常使用
    cl_device_id device_id = cl.GetDeviceID();
    BOOST_REQUIRE(device_id != nullptr);

    // 检查一些设备信息以验证设备是否有效
    char   device_name[256];
    cl_int err = clGetDeviceInfo(
        device_id, CL_DEVICE_NAME, sizeof(device_name), device_name, nullptr);
    BOOST_CHECK_EQUAL(err, CL_SUCCESS);

    cl_ulong global_mem_size = 0;
    err                      = clGetDeviceInfo(device_id,
                          CL_DEVICE_GLOBAL_MEM_SIZE,
                          sizeof(global_mem_size),
                          &global_mem_size,
                          nullptr);
    BOOST_CHECK_EQUAL(err, CL_SUCCESS);
    BOOST_CHECK_GT(global_mem_size, 0);  // 全局内存大小应大于0

    cl.DeInit();
}
